package com.yunhai.recipe.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yunhai.common.dto.GlobalException;
import com.yunhai.common.dto.PaginationVo;
import com.yunhai.common.utils.ObjectUtil;
import com.yunhai.common.utils.ReflectionCopy;
import com.yunhai.model.entity.fms.FmsMaterialCategoryEntity;
import com.yunhai.model.entity.fms.FmsMaterialConfigEntity;
import com.yunhai.model.entity.fms.FmsMaterialUnitEntity;
import com.yunhai.model.vo.fms.FmsMaterialConfigImportVo;
import com.yunhai.model.vo.fms.FmsMaterialConfigQuery;
import com.yunhai.model.vo.fms.FmsMaterialConfigVo;
import com.yunhai.recipe.listener.MaterialConfigBatchLoadListener;
import com.yunhai.recipe.mapper.FmsMaterialConfigMapper;
import com.yunhai.recipe.service.FmsCodeDictService;
import com.yunhai.recipe.service.FmsMaterialCategoryService;
import com.yunhai.recipe.service.FmsMaterialConfigService;
import com.yunhai.recipe.service.FmsMaterialUnitService;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class FmsMaterialConfigServiceImpl implements FmsMaterialConfigService {

    @Resource
    private FmsMaterialConfigMapper fmsMaterialConfigMapper;
    @Resource
    private FmsMaterialUnitService fmsMaterialUnitService;
    @Resource
    private FmsMaterialCategoryService fmsMaterialCategoryService;
    @Resource
    private FmsCodeDictService fmsCodeDictService;
    /**
     * 获取 FmsMaterialConfig 分页列表
     */
    @Transactional
    public IPage getFmsMaterialConfigPagination(PaginationVo paginationVo, FmsMaterialConfigQuery fmsMaterialConfigQuery ) throws Exception {

        IPage page = new Page( paginationVo.getPageIndex(), paginationVo.getPageSize() );
        LambdaQueryWrapper<FmsMaterialConfigEntity> lqs = new LambdaQueryWrapper();
        lqs.orderByDesc( FmsMaterialConfigEntity::getCreateTime );
        lqs.eq(fmsMaterialConfigQuery.getEnabled()!=null, FmsMaterialConfigEntity::getEnabled, fmsMaterialConfigQuery.getEnabled());

        lqs.likeRight(fmsMaterialConfigQuery.getNumber() !=null, FmsMaterialConfigEntity::getNumber, fmsMaterialConfigQuery.getNumber());
        lqs.likeRight(fmsMaterialConfigQuery.getName() !=null, FmsMaterialConfigEntity::getName, fmsMaterialConfigQuery.getName());
        lqs.eq( fmsMaterialConfigQuery.getMaterialTypeNumber()!= null,
                FmsMaterialConfigEntity::getMaterialTypeNumber,
                fmsMaterialConfigQuery.getMaterialTypeNumber());

        fmsMaterialConfigMapper.selectPage(page, lqs);

        List<FmsMaterialConfigEntity> record = page.getRecords();
        if( !ObjectUtil.isNotEmptyList(record)){
            return page;
        }

        //获取物料类型
        Set<Long> unitIds = record.stream().map(item->item.getUnitId()).collect(Collectors.toSet());
        if( ObjectUtil.isNotEmptyList(unitIds) ) {
            List<FmsMaterialUnitEntity> unitList = fmsMaterialUnitService.getUnitListByIds(unitIds);
            if (ObjectUtil.isNotEmptyList(unitList)) {
                for (FmsMaterialConfigEntity item : record) {
                    unitList.stream().filter(row -> row.getId().equals(item.getUnitId())).findFirst().ifPresent(row -> {
                        item.setUnitName(row.getName());
                        item.setUnitNumber(row.getNumber());
                    });
                }
            }
        }

        //获取物料单位
        Set<Long> materialTypeId = record.stream().map(item->item.getMaterialTypeId()).collect(Collectors.toSet());
        if( ObjectUtil.isNotEmptyList(unitIds) ) {
            List<FmsMaterialCategoryEntity> materialTypeList = fmsMaterialCategoryService.getMaterialCategoryListByIds(materialTypeId);
            if (ObjectUtil.isNotEmptyList(materialTypeList)) {
                for (FmsMaterialConfigEntity item : record) {
                    materialTypeList.stream().filter(row -> row.getId().equals(item.getMaterialTypeId())).findFirst().ifPresent(row -> {
                        item.setMaterialTypeName(row.getMaterialTypeName());
                        item.setMaterialTypeNumber(row.getMaterialTypeNumber());
                    });
                }
            }
        }
        return page;
    }

    /**
     * 获取 FmsMaterialConfig 所有数据
     *
    */
    @Transactional
    public List<FmsMaterialConfigEntity> getFmsMaterialConfigAllList( FmsMaterialConfigQuery fmsMaterialConfigQuery ) throws Exception {

        LambdaQueryWrapper<FmsMaterialConfigEntity> lqs = new LambdaQueryWrapper();
        lqs.eq(FmsMaterialConfigEntity::getEnabled, 0);
        List<FmsMaterialConfigEntity> list = fmsMaterialConfigMapper.selectList(lqs);
        return list;
    }


    /**
     * 获取 FmsMaterialConfig 详情
    */
    @Transactional
    public FmsMaterialConfigEntity getFmsMaterialConfigDetail( Long id) throws Exception {

        FmsMaterialConfigEntity fmsMaterialConfig = fmsMaterialConfigMapper.selectById(id);
        return fmsMaterialConfig;
    }


    /**
     * 新增 FmsMaterialConfig
     * */
    @Transactional
    public void addFmsMaterialConfig(FmsMaterialConfigVo fmsMaterialConfigVo) throws Exception {

        FmsMaterialConfigEntity fmsMaterialConfig = new FmsMaterialConfigEntity();
        ReflectionCopy.copyProperties( fmsMaterialConfig, fmsMaterialConfigVo );
        fmsMaterialConfigMapper.insert(fmsMaterialConfig);

        fmsCodeDictService.updateById(5L, fmsMaterialConfigVo.getNumber());
        return;
    }


    /**
     * 更新 FmsMaterialConfig
     * */
    @Transactional
    public void updateFmsMaterialConfig( FmsMaterialConfigVo fmsMaterialConfigVo) throws Exception {

        if( fmsMaterialConfigVo.getId() == null ){
            throw GlobalException.gen(10021, "id不存在");
        }
        FmsMaterialConfigEntity fmsMaterialConfig = new FmsMaterialConfigEntity();
        ReflectionCopy.copyProperties( fmsMaterialConfig, fmsMaterialConfigVo );
        fmsMaterialConfigMapper.updateById(fmsMaterialConfig);
        return;
    }

    /**
     * 删除 FmsMaterialConfig
     * */
    @Transactional
    public void batchRemoveFmsMaterialConfig( List<Long> ids ) throws Exception {


        if( !ObjectUtil.isNotEmptyList(ids) ){
            throw GlobalException.gen(10011, "要删除的id不存在");
        }
        fmsMaterialConfigMapper.deleteBatchIds(ids);
    }

    @Override
    public List<FmsMaterialConfigEntity> getRecipeByIds(List<Long> ids) throws Exception {
         return  fmsMaterialConfigMapper.selectBatchIds(ids);
    }

    @Override
    public void addImportExcelFile(MultipartFile file) throws Exception {

//        FmsMaterialConfigVo

        //记录本次导出操作，以及数据库中的 material number 的最大值。对 number 数据库的值进行调整。
        String curMaterialConfigNumber = "";

        MaterialConfigBatchLoadListener listener = new MaterialConfigBatchLoadListener();
        EasyExcel.read(file.getInputStream(), FmsMaterialConfigImportVo.class,listener).sheet().doRead();;
        List<FmsMaterialConfigImportVo> list = listener.getList();


        List<FmsMaterialUnitEntity> fmsMaterialUnitAllList = fmsMaterialUnitService.getFmsMaterialUnitAllList(null);
        List<FmsMaterialCategoryEntity> fmsMaterialCategoryAllList = fmsMaterialCategoryService.getFmsMaterialCategoryAllList(null);


        List<FmsMaterialConfigEntity> entityList = new ArrayList<>();
        for( FmsMaterialConfigImportVo item : list ){
            FmsMaterialConfigEntity entity = new FmsMaterialConfigEntity();
            entity.setNumber(item.getNumber())
                    .setName(item.getName())
                    .setSrcMaterialId(item.getSrcMaterialId())
                    .setExpirationDate(item.getExpirationDate())
                    .setFreezeExpirationDate(item.getFreezeExpirationDate())
                    .setDisinfectCycle(item.getDisinfectCycle())
                    .setMaterialConversionCoefficient( (int) (item.getMaterialConversionCoefficient()* 1000) )
                    .setPortion(item.getPortion())
                    .setRemark(item.getRemark())
                    .setCreateTime(item.getCreateTime());


            //处理 “计量单位”  unitName
            if( fmsMaterialUnitAllList != null ){
                fmsMaterialCategoryAllList.stream()
                        .filter( row->row.getMaterialTypeName().equals( item.getMaterialTypeName() ) )
                        .findFirst().ifPresent(
                        row->{
                            entity.setMaterialTypeId( row.getId() );
                            entity.setMaterialTypeNumber( row.getMaterialTypeNumber() );
                            entity.setMaterialTypeName(row.getMaterialTypeName());
                        }
                );
            }

            //处理 “物料类型”  materialTypeName
            if( fmsMaterialUnitAllList != null ){
                fmsMaterialUnitAllList.stream()
                        .filter( row->row.getName().equals( item.getUnitName() ) )
                        .findFirst().ifPresent(
                                row->{
                                    entity.setUnitId( row.getId() );
                                    entity.setUnitNumber( row.getNumber() );
                                    entity.setUnitName(row.getName());
                                }
                        );
            }

            //处理 enabled
            if( "启用".equals(item.getEnabled()) ){
                entity.setEnabled(0);
            }else {
                entity.setEnabled(1);
            }

            //处理 为性状易受影响物料 sticky
            if( "否".equals( item.getSticky() ) ){
                entity.setSticky(0);
            }else {
                entity.setSticky(1);
            }

            //处理 始终单独出料 alwaysDischargeSeparately
            if( "否".equals(item.getAlwaysDischargeSeparately()) ){
                entity.setAlwaysDischargeSeparately(0);
            }else {
                entity.setAlwaysDischargeSeparately(1);
            }

            //处理 强制扫码补料 forcedScanning
            if( "否".equals( item.getForcedScanning() ) ){
                entity.setForceDisinfect(0);
            }else {
                entity.setForceDisinfect(1);
            }

            //处理 强制丢弃标识 forceThrow
            if( "否".equals( item.getForceThrow() ) ){
                entity.setForceThrow(0);
            }else {
                entity.setForceThrow(1);
            }


            //处理 是否支持萃取 extracted
            if( "否".equals( item.getExtracted() ) ){
                entity.setExtracted(0);
            }else {
                entity.setExtracted(1);
            }

            entityList.add(entity);
        }


        //获取所有的物料，如果 "编号" 或者 "名称相同"，则直接过滤掉.
        List<FmsMaterialConfigEntity> fmsMaterialConfigAllList = this.getFmsMaterialConfigAllList(null);
        if( fmsMaterialConfigAllList == null ){
            fmsMaterialConfigAllList = new ArrayList<FmsMaterialConfigEntity>();
        }

        for( FmsMaterialConfigEntity entity : entityList ){

            List filterList = fmsMaterialConfigAllList.stream().filter( item->{
               return item.getNumber().equals(entity.getNumber()) || item.getName().equals(entity.getName());
            } ).collect(Collectors.toList());
            if( filterList.size() > 0 ){
                continue;
            }
            fmsMaterialConfigMapper.insert(entity);
        }

        Set<String> numberSet = fmsMaterialConfigAllList.stream().map(item->item.getNumber()).collect(Collectors.toSet());
        Set<String> numberSet_1 = entityList.stream().map(item->item.getNumber()).collect(Collectors.toSet());
        numberSet.addAll(numberSet_1);
        String value = findMaxAsciiString(numberSet);
        fmsCodeDictService.updateById(5L, value);

        System.out.println(list);
    }

    @Override
    public void exportExcelFile(HttpServletResponse response) throws Exception {


        List<FmsMaterialCategoryEntity> typeList = fmsMaterialCategoryService.getFmsMaterialCategoryAllList(null);
        List<FmsMaterialUnitEntity> unitList = fmsMaterialUnitService.getFmsMaterialUnitAllList(null);

        //获取所有数据，然后转换为 import 类型
        List<FmsMaterialConfigEntity> fmsMaterialConfigAllList = this.getFmsMaterialConfigAllList(null);
        if( fmsMaterialConfigAllList == null ){
            fmsMaterialConfigAllList = new ArrayList<>();
        }

        List<FmsMaterialConfigImportVo> dataList = new ArrayList<>();
        for( FmsMaterialConfigEntity item : fmsMaterialConfigAllList ){
            FmsMaterialConfigImportVo importVo  = new FmsMaterialConfigImportVo();
            importVo.setName(item.getName());
            importVo.setNumber(item.getNumber());
            importVo.setRemark(item.getRemark());
            importVo.setCreateTime(item.getCreateTime());
            importVo.setPortion(item.getPortion());
            importVo.setDisinfectCycle(item.getDisinfectCycle());
            importVo.setFreezeExpirationDate(item.getFreezeExpirationDate());
            importVo.setExpirationDate(item.getExpirationDate());
            importVo.setMaterialConversionCoefficient((double)item.getMaterialConversionCoefficient()/1000);
            importVo.setSrcMaterialId(item.getSrcMaterialId());
            if( ObjectUtil.isNotEmptyList(typeList) ){
                typeList.stream().filter( row->{
                    return row.getId().equals( item.getMaterialTypeId() );
                } ).findFirst().ifPresent(row->{
                    importVo.setMaterialTypeName(row.getMaterialTypeName());
                });
            }
            if( ObjectUtil.isNotEmptyList(unitList) ){
                unitList.stream().filter( row->{
                    return row.getId().equals( item.getUnitId() );
                } ).findFirst().ifPresent(row->{
                    importVo.setUnitName(row.getName());
                });
            }

            if( item.getExtracted() == null  || item.getExtracted() .equals(0) ){
                importVo.setExtracted("否");
            }else {
                importVo.setExtracted("是");
            }

            if( item.getForceThrow() == null  || item.getForceThrow() .equals(0) ){
                importVo.setForceThrow("否");
            }else {
                importVo.setForceThrow("是");
            }

            if( item.getForcedScanning() == null  || item.getForcedScanning() .equals(0) ){
                importVo.setForcedScanning("否");
            }else {
                importVo.setForcedScanning("是");
            }

            if( item.getAlwaysDischargeSeparately() == null  || item.getAlwaysDischargeSeparately() .equals(0) ){
                importVo.setAlwaysDischargeSeparately("否");
            }else {
                importVo.setAlwaysDischargeSeparately("是");
            }

            if( item.getForceDisinfect() == null  || item.getForceDisinfect() .equals(0) ){
                importVo.setForceDisinfect("否");
            }else {
                importVo.setForceDisinfect("是");
            }


            if( item.getSticky() == null  || item.getSticky() .equals(0) ){
                importVo.setSticky("否");
            }else {
                importVo.setSticky("是");
            }

            if( item.getEnabled() == null  || item.getEnabled() .equals(0) ){
                importVo.setEnabled("启用");
            }else {
                importVo.setEnabled("禁用");
            }

            dataList.add(importVo);
        }


        // 2. 设置响应头（关键：避免中文乱码）
        String fileName = "物料配置_" + System.currentTimeMillis() + ".xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition",
                "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));

        // 3. 执行导出（直接写入响应流）
        EasyExcel.write(response.getOutputStream(), FmsMaterialConfigImportVo.class)
                .sheet("物料配置")
                .registerWriteHandler(getHeadStyleStrategy())
                .doWrite(dataList);
    }


    private HorizontalCellStyleStrategy getHeadStyleStrategy() {
        // 1. 创建表头单元格样式
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();

        // 2. 设置表头字体（大小、颜色、笔锋/加粗）
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 10); // 字体大小（单位：磅，1磅≈0.35毫米）
        headWriteFont.setColor(IndexedColors.BLACK.getIndex()); // 字体颜色（白色）
        headWriteFont.setBold(false); // 笔锋效果（加粗，true为加粗）
        headWriteCellStyle.setWriteFont(headWriteFont); // 将字体应用到表头样式

        // 3. 设置表头背景色（可选，增强视觉效果）
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex()); // 背景色（深蓝色）
        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); // 填充模式（纯色）

        // 4. 设置表头对齐方式（可选，使内容居中）
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); // 水平居中
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
        headWriteCellStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
        headWriteCellStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
        headWriteCellStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
        headWriteCellStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());

        // 创建内容样式
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        WriteFont contentWriteFont = new WriteFont();
        contentWriteFont.setFontHeightInPoints((short) 10); // 字体大小
        contentWriteFont.setFontName("宋体"); // 字体名称
        contentWriteFont.setBold(false); // 加粗
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); // 水平居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
        contentWriteCellStyle.setWrapped(true); // 自动换行
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        contentWriteCellStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
        contentWriteCellStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
        contentWriteCellStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
        contentWriteCellStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());

        // 7. 返回样式策略（表头样式+内容样式）
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }

    public static String findMaxAsciiString(Set<String> stringSet) {
        if (stringSet.isEmpty()) {
            return null; // 处理空集合
        }
        String maxString = null;
        for (String str : stringSet) {
            if (maxString == null || str.compareTo(maxString) > 0) {
                maxString = str; // 更新最大字符串
            }
        }
        return maxString;
    }

}

      